package com.yuke.cloud.service.uac.service.impl;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.yuke.cloud.common.base.constant.GlobalConstant;
import com.yuke.cloud.common.base.dto.LoginAuthDto;
import com.yuke.cloud.common.base.enums.ErrorCodeEnum;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.common.util.Collections3;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.service.api.smc.dto.ShopInfoDto;
import com.yuke.cloud.service.api.smc.service.SmcFeignApi;
import com.yuke.cloud.service.api.uac.exceptions.UacBizException;
import com.yuke.cloud.service.api.wmc.dto.WarehouseInfoDto;
import com.yuke.cloud.service.api.wmc.service.WmcStorageFeignApi;
import com.yuke.cloud.service.uac.dao.AccEmployeeGroupMapper;
import com.yuke.cloud.service.uac.dao.AccGroupMapper;
import com.yuke.cloud.service.uac.dao.AccUserGroupMapper;
import com.yuke.cloud.service.uac.dao.AccUserRoleMapper;
import com.yuke.cloud.service.uac.dto.BindUserDto;
import com.yuke.cloud.service.uac.dto.GroupBindUserDto;
import com.yuke.cloud.service.uac.dto.GroupBindUserReqDto;
import com.yuke.cloud.service.uac.dto.UserGroupDto;
import com.yuke.cloud.service.uac.entity.AccEmployeeGroup;
import com.yuke.cloud.service.uac.entity.AccGroup;
import com.yuke.cloud.service.uac.entity.AccUser;
import com.yuke.cloud.service.uac.entity.AccUserGroup;
import com.yuke.cloud.service.uac.service.AccUserGroupService;
import com.yuke.cloud.service.uac.service.AccUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;


/**
 * Created by wg on 2018/09/15.
 */
@Service
@Transactional
public class AccUserGroupServiceImpl extends BaseService<AccUserGroup> implements AccUserGroupService {
    @Resource
    private AccUserGroupMapper accUserGroupMapper;
    @Resource
    private AccGroupMapper accGroupMapper;
    @Resource
    private AccUserRoleMapper accUserRoleMapper;
    @Resource
    private AccUserService accUserService;
    @Resource
    private WmcStorageFeignApi wmcStorageFeignApi;
    @Resource
    private AccEmployeeGroupMapper accEmployeeGroupMapper;
    @Resource
    private SmcFeignApi smcFeignApi;

    //根据用户ID删除组关系
    public int deleteUserGroupByUserId(Long userId) {

        Preconditions.checkArgument(userId != null, "用户id为空");
        Preconditions.checkArgument(!Objects.equals(userId, GlobalConstant.Sys.SUPER_MANAGER_USER_ID), "超级管理员不能删除");

        // 判断用户是否存在
//        AccUserGroup userGroup = accUserGroupMapper.selectByPrimaryKey(userId);
        Example example = new Example(AccUserGroup.class);
        Example.Criteria criteria= example.createCriteria();
        criteria.andEqualTo("userId", userId);

        AccUserGroup userGroup = accUserGroupMapper.selectOneByExample(example);
        if (PublicUtil.isEmpty(userGroup)) {
            throw new UacBizException(ErrorCodeEnum.UAC10011011, userId);
        }

//        return mapper.deleteByPrimaryKey(userId);
        return accUserGroupMapper.deleteByExample(example);
    }

    @Override
    public UserGroupDto selectUserGroupInfoByUserId(Long userId) {
        UserGroupDto userGroupDto = new UserGroupDto();
        userGroupDto = accUserGroupMapper.selectUserGroupInfoByUserId(userId);
        Long groupId =0L;
        if (userGroupDto!=null){
            groupId = userGroupDto.getGroupId();
            if (userGroupDto.getLevel().toString().equals("3")){
                groupId = userGroupDto.getParentId();
            }
            List<WarehouseInfoDto> warehouseInfoDto = wmcStorageFeignApi.getWarehouseInfoByGroupId(groupId);

            if (warehouseInfoDto != null && warehouseInfoDto.size()>0){
                userGroupDto.setWarehouseId(warehouseInfoDto.get(0).getWarehouseId());
                userGroupDto.setWarehouseName(warehouseInfoDto.get(0).getWarehouseName());
            }
        }else{
            //可能是店家
            List<ShopInfoDto> shopInfoDtos = smcFeignApi.getShopInfoDtoByUserId(userId);
            if (shopInfoDtos!=null && shopInfoDtos.size()>0 ){
                Long shopId = shopInfoDtos.get(0).getShopId();
                List<Long> shopList = new ArrayList<>();
                shopList.add(shopId);
                List<Map> maps = wmcStorageFeignApi.getWarehouseName(shopList);

                if (maps != null && maps.size()>0){
                     if (maps.get(0).get("warehouseId")!=null){
                        String warehouseId = String.valueOf(maps.get(0).get("warehouseId"));
                        userGroupDto.setWarehouseId(Long.valueOf(warehouseId));
                        userGroupDto.setWarehouseName(maps.get(0).get("warehouseName").toString());
                    }

                }

            }
        }

        return userGroupDto;
    }

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public GroupBindUserDto getGroupBindUserDto(Long groupId, Long currentUserId) {
        GroupBindUserDto groupBindUserDto = new GroupBindUserDto();
        Set<Long> alreadyBindUserIdSet = Sets.newHashSet();
        AccGroup accGroup = accGroupMapper.selectByPrimaryKey(groupId);
        if (PublicUtil.isEmpty(accGroup)) {
            logger.error("找不到uacGroup={}, 的组织", accGroup);
            throw new UacBizException(ErrorCodeEnum.UAC10015001, groupId);
        }

        // 查询所有用户包括已禁用的用户及已绑定到其他组织的用户（绑定到其他组织的用户为disabled）
        List<BindUserDto> bindUserDtoList;
        if (GlobalConstant.Sys.GROUP_SUPPLIER == groupId || GlobalConstant.Sys.GROUP_SHOPPER == groupId) {  // 供应商与商家用户只能通过申请绑定，不能直接处理
            bindUserDtoList = accUserGroupMapper.selectAllNeedBindUserEx(GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID, currentUserId);
        } else {
            // mod by wg 20181220 超级管理员也可以对其他管理员进行组织绑定
            if (currentUserId == GlobalConstant.Sys.SUPER_MANAGER_USER_ID) {
                bindUserDtoList = accUserGroupMapper.selectAllNeedBindUserExAdmin(GlobalConstant.Sys.SUPER_MANAGER_USER_ID);
            }else {
                bindUserDtoList = accUserGroupMapper.selectAllNeedBindUser(GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID, currentUserId/*, groupId*/);
            }
        }

        // 该组织已经绑定的用户
        //List<AccUserGroup> setAlreadyBindUserSet = accUserGroupMapper.listByGroupId(groupId);
        List<AccEmployeeGroup> setAlreadyBindUserSet = accEmployeeGroupMapper.listByGroupId(groupId);

        Set<BindUserDto> allUserSet = new HashSet<>(bindUserDtoList);

        for (AccEmployeeGroup accUserGroup : setAlreadyBindUserSet) {
            alreadyBindUserIdSet.add(accUserGroup.getUserId());
        }

        groupBindUserDto.setAllUserSet(allUserSet);
        groupBindUserDto.setAlreadyBindUserIdSet(alreadyBindUserIdSet);

        return groupBindUserDto;
    }

    /**
     * Bind uac user 4 group int.
     *
     * @param groupBindUserReqDto the group bind user req dto
     * @param authResDto          the auth res dto
     */
    @Override
    public void bindUacUser4Group(GroupBindUserReqDto groupBindUserReqDto, LoginAuthDto authResDto) {
        if (groupBindUserReqDto == null) {
            logger.error("参数不能为空");
            throw new IllegalArgumentException("参数不能为空");
        }

        Long groupId = groupBindUserReqDto.getGroupId();
        Long loginUserId = authResDto.getUserId();
        List<Long> userIdList = groupBindUserReqDto.getUserIdList();

        if (null == groupId) {
            throw new IllegalArgumentException("组织ID不能为空");
        }

        AccGroup group = accGroupMapper.selectByPrimaryKey(groupId);

        if (group == null) {
            logger.error("找不到组织信息 groupId={}", groupId);
            throw new UacBizException(ErrorCodeEnum.UAC10015001, groupId);
        }

        if (PublicUtil.isNotEmpty(userIdList) && userIdList.contains(loginUserId)) {
            logger.error("不能操作当前登录用户 userId={}", loginUserId);
            throw new UacBizException(ErrorCodeEnum.UAC10011023);
        }

        // 查询超级管理员用户Id集合
        List<Long> superUserList = accUserRoleMapper.listSuperUser(GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID);
        List<Long> unionList = Collections3.intersection(userIdList, superUserList);
        // mod by wg 20181220 增加条件&& authResDto.getUserId() != GlobalConstant.Sys.SUPER_MANAGER_USER_ID，超级管理员可以对其他管理员操作
        // mod by wg 20190716
//        if (PublicUtil.isNotEmpty(superUserList) && superUserList.contains(GlobalConstant.Sys.SUPER_MANAGER_USER_ID)) {
        if (PublicUtil.isNotEmpty(unionList) && unionList.contains(GlobalConstant.Sys.SUPER_MANAGER_USER_ID)) {
            logger.error("不能操作超级管理员用户 超级用户={}", unionList);
            throw new UacBizException(ErrorCodeEnum.UAC10011023);
        }

        if (PublicUtil.isNotEmpty(userIdList) && PublicUtil.isNotEmpty(unionList)
                && authResDto.getUserId() != GlobalConstant.Sys.SUPER_MANAGER_USER_ID) {
            logger.error("不能操作超级管理员用户 超级用户={}", unionList);
            throw new UacBizException(ErrorCodeEnum.UAC10011023);
        }

        // 已绑定、待绑定、待取消绑定用户的关系计算
        List<AccEmployeeGroup> groupUsers = accEmployeeGroupMapper.listByGroupId(groupId);

        List<Long> oldUserIdList = Lists.newArrayList();
        for (AccEmployeeGroup accEmployeeGroup : groupUsers) {
            oldUserIdList.add(accEmployeeGroup.getUserId());
        }

        List<Long> notDelList = Collections3.intersection(userIdList, oldUserIdList);  // 找出在待绑定的用户中已经绑定的用户
        List<Long> delList = Collections3.subtract(oldUserIdList, notDelList);  // 找出在原有绑定的用户中需要解绑的用户
        List<Long> addList = Collections3.subtract(userIdList, notDelList);  // 找出新的待绑定用户

        // 1. 先取消对该组织的用户绑定(不包含超级管理员用户及已经在要待绑定的用户)
        if (PublicUtil.isNotEmpty(groupUsers)) {

            if (PublicUtil.isEmpty(notDelList)) {
                notDelList = null;
            }

            // mod by wg 20181220 如果当前用户是超级管理员，可以对其他管理员进行操作
            if (authResDto.getUserId().equals(GlobalConstant.Sys.SUPER_MANAGER_USER_ID)) {
                accEmployeeGroupMapper.deleteExcludeSuperMngExAdmin(groupId, GlobalConstant.Sys.SUPER_MANAGER_USER_ID, notDelList);
            }else {
                accEmployeeGroupMapper.deleteExcludeSuperMng(groupId, GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID, notDelList);
            }

            // 修改用户表is_employee字段为默认消费者
//            accUserService.updateIsEmployeeByIds(userIdList, false);

            // 取消原有不在该组织用户的类型的设置
            accUserService.modifyUserTypeByIds(delList, groupId, false);

        }

        if (PublicUtil.isEmpty(userIdList)) {
            // 取消该组织的所有用户的绑定
            logger.info("取消绑定所有非超级管理员用户成功");
            return;
        }

        // 绑定所选用户,如果该用户绑定了其他部门，必须先解绑其他部门
        for (Long userId : addList) {
            AccUser accUser = accUserService.queryByUserId(userId);
            if (PublicUtil.isEmpty(accUser)) {
                logger.error("找不到绑定的用户 userId={}", userId);
                throw new UacBizException(ErrorCodeEnum.UAC10011024, userId);
            }
            //todo 20191112 如果该用户绑定了其他部门，必须先解绑其他部门
            Example example = new Example(AccUserGroup.class);
            Example.Criteria criteria= example.createCriteria();
            criteria.andEqualTo("userId",userId);
            List<AccEmployeeGroup> aaa = accEmployeeGroupMapper.selectByExample(example);
            if (aaa!=null && aaa.size()>0){
                for(AccEmployeeGroup item : aaa){
                    accEmployeeGroupMapper.delete(item);
                }
            }

            AccEmployeeGroup accEmployeeGroup = new AccEmployeeGroup();
            accEmployeeGroup.setEmployeeGroupId(generateId());
            accEmployeeGroup.setUserId(userId);
            accEmployeeGroup.setGroupId(groupId);
            accEmployeeGroupMapper.insertSelective(accEmployeeGroup);
        }

        // 修改用户表is_employee字段，系统一共只有4种类型的用户
        // 设置用户类型
        if (PublicUtil.isNotEmpty(addList)) {
            if ((GlobalConstant.Sys.GROUP_CUSTOMER.equals(groupId)
                    || GlobalConstant.Sys.GROUP_SHOPPER.equals(groupId)
                    || GlobalConstant.Sys.GROUP_SUPPLIER.equals(groupId))) {
//                accUserService.updateIsEmployeeByIds(userIdList, false);
                accUserService.modifyUserTypeByIds(addList, groupId, true);
            }else {
//                accUserService.updateIsEmployeeByIds(userIdList, true);
                accUserService.modifyUserTypeByIds(addList, GlobalConstant.Sys.GROUP_COMPANY, true);
            }
        }
    }

    @Override
    public List<AccUserGroup> getByUserIdAndGroupId(Long userId, Long groupId) {
        Example example = new Example(AccUserGroup.class);
        Example.Criteria criteria= example.createCriteria();
        criteria.andEqualTo("userId", userId).andEqualTo("groupId",groupId);

        List<AccUserGroup> list = accUserGroupMapper.selectByExample(example);

        return list;
    }

    @Override
    public Long generateUserGroupId() {
        return generateId();
    }

    @Override
    public void updateUserGroup(Long userId, Long groupId) {
        AccUserGroup accUserGroup = new AccUserGroup();
        accUserGroup.setUserId(userId);
        List<AccUserGroup> acg= accUserGroupMapper.select(accUserGroup);
        accUserGroup.setGroupId(groupId);
        if (acg != null && acg.size() > 0){
            accUserGroup.setUserGroupId(acg.get(0).getUserGroupId());
            accUserGroupMapper.updateByPrimaryKeySelective(accUserGroup);
        }else{
            accUserGroup.setUserGroupId(this.generateId());
            accUserGroupMapper.insert(accUserGroup);
        }

    }
}
